package com.tarena.lbs.basic.web.service;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.github.pagehelper.PageInfo;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.basic.web.repository.AdminRepository;
import com.tarena.lbs.basic.web.repository.BusinessCategoryRepository;
import com.tarena.lbs.basic.web.repository.BusinessRepository;
import com.tarena.lbs.basic.web.repository.StoreRepository;
import com.tarena.lbs.common.passport.enums.Roles;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.common.security.utils.LbsSecurityContenxt;
import com.tarena.lbs.pojo.attach.param.PicUpdateParam;
import com.tarena.lbs.pojo.basic.param.BusinessParam;
import com.tarena.lbs.pojo.basic.po.AdminPO;
import com.tarena.lbs.pojo.basic.po.BusinessCategoryPO;
import com.tarena.lbs.pojo.basic.po.BusinessPO;
import com.tarena.lbs.pojo.basic.po.StorePO;
import com.tarena.lbs.pojo.basic.query.BusinessQuery;
import com.tarena.lbs.pojo.basic.vo.BusiStoreVO;
import com.tarena.lbs.pojo.basic.vo.BusinessCategoryVO;
import com.tarena.lbs.pojo.basic.vo.BusinessVO;
import com.tarena.lbs.pojo.basic.vo.StoreVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BusinessService {
    @Autowired
    private BusinessRepository businessRepository;
    @Autowired
    private BusinessCategoryRepository businessCategoryRepository;
    @Autowired
    private AdminRepository adminRepository;
    @DubboReference
    private AttachApi attachApi;
    @Autowired
    private StoreRepository storeRepository;
    public PageResult<BusinessVO> businessPage(BusinessQuery query) throws BusinessException {
        //添加业务数据权限 如果是SHOP角色 query条件要封装一个非空字段businessId
        UserPrinciple userPrinciple = LbsSecurityContenxt.getLoginToken();
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","用户认证失败"));
        Roles role=userPrinciple.getRole();
        Integer adminId=userPrinciple.getId();
        if (role==Roles.SHOP){
            AdminPO adminPO = adminRepository.getAdminById(adminId);
            query.setBusinessId(adminPO.getBusinessId());
        }
        //1. pageHelper插件 使用仓储层返回PageInfo
        PageInfo<BusinessPO> poPageInfo= businessRepository.getBusinessPage(query);
        //2. 准备一个空的PageResult pageNo(query) pageSize(query) total(PageInfo) objects(PageInfo)列表
        PageResult<BusinessVO> voPages=new PageResult<>();
        voPages.setPageNo(query.getPageNo());
        voPages.setPageSize(query.getPageSize());
        voPages.setTotal(poPageInfo.getTotal());
        //3. 根据pageInfo total值是否>0 决定是否给pageResult封装objects
        List<BusinessVO> vos=null;
        if(poPageInfo.getTotal()>0) {
            //4. 封装时才转化 po 变成 vo
            vos=poPageInfo.getList().stream().map(po->{
                BusinessVO vo=new BusinessVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }).collect(Collectors.toList());
        }
        voPages.setObjects(vos);
        return voPages;

    }


    public List<BusinessCategoryVO> categoryList() {
        List<BusinessCategoryPO> pos=businessCategoryRepository.getCategoryList();
        List<BusinessCategoryVO> vos=null;
        if (pos!=null&&pos.size()>0){
            vos=pos.stream().map(po->{
                BusinessCategoryVO vo=new BusinessCategoryVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }).collect(Collectors.toList());
        }
        return vos;
    }
    //默认transactional 只对runtimeException回滚
    @Transactional(rollbackFor = Exception.class)
    public void businessSave(BusinessParam param) throws BusinessException {
        //1.拿到登录用户 可能拿不到 可能拿到
        UserPrinciple userPrinciple= LbsSecurityContenxt.getLoginToken();
        //2.判断
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","用户认证失败"));
        //3.获取他的枚举角色
        Roles role = userPrinciple.getRole();
        Asserts.isTrue(role!=Roles.ADMIN,new BusinessException("-2","用户没有权限"));
        //4.幂等设计 只允许存在一个businessName的商家 如果已经有了就不增了
        String businessName=param.getBusinessName();
        Long total=businessRepository.countByName(businessName);
        Asserts.isTrue(total!=0,new BusinessException("-2","已经存在当前商家:"+businessName));
        BusinessPO poParam=new BusinessPO();
        BeanUtils.copyProperties(param,poParam);
        poParam.setBusinessStatus(2);
        poParam.setAuditRemarks("同意");
        poParam.setEntryTime(new Date());
        businessRepository.saveBusiness(poParam);
        Integer businessId=poParam.getId();
        Integer businessTypeLiscence=100;
        Integer businessTypeLogo=200;
        //5.绑定图片 业务提供2个字段属性 business_id(是谁的传谁的id) business_type(人为类型数值)
        List<PicUpdateParam> params=new ArrayList<>();
        //5.1绑定的营业执照 fileUuid businessId type=100
        PicUpdateParam licenceParam=new PicUpdateParam();
        licenceParam.setBusinessId(businessId);
        licenceParam.setBusinessType(businessTypeLiscence);
        //licenceUrl: http://localhost:9081/static/230hf30hf932f032h.png
        log.info("当前营业执照的url:{}和logo的url:{}",param.getBusinessLicense(),param.getBusinessLogo());
        String licenceUuid=param.getBusinessLicense().split("/")[4];
        licenceParam.setFileUuid(licenceUuid);
        params.add(licenceParam);
        //5.2 logo
        PicUpdateParam logoParam=new PicUpdateParam();
        logoParam.setBusinessId(businessId);
        logoParam.setBusinessType(businessTypeLogo);
        String logoUuid=param.getBusinessLogo().split("/")[4];
        logoParam.setFileUuid(logoUuid);
        params.add(logoParam);
        //5.3 调用方 应该关心绑定结果,而不关心绑定过程 和过程异常
        try{
            boolean result=attachApi.batchUpdateBusiness(params);
            if (!result){
                throw new BusinessException("-2","图片绑定失败");
            }
        }catch (BusinessException e){
            log.error("图片绑定不成功",e);
            throw e;
        }catch (Exception e){
            log.error("远程调用失败",e);
            throw e;
        }
    }

    public BusiStoreVO businessDetail(Integer id) {
        //1.查询businessPO详情
        BusinessPO businessPO = businessRepository.getBusiness(id);
        //2.非空的时候 店铺绑定businessId 查询店铺的列表数据
        List<StorePO> storePOList=null;
        BusiStoreVO vo=new BusiStoreVO();
        if (businessPO!=null){
            storePOList=storeRepository.getStoresByBizId(id);
            BeanUtils.copyProperties(businessPO,vo);
        }
        //3.封装 BusiStoreVO 里面StoreVO
        if (CollectionUtils.isNotEmpty(storePOList)){
            //不仅business有值,下面也有店铺信息
            List<StoreVO> storeVos=storePOList.stream().map(po->{
                        StoreVO vo1=new StoreVO();
                        BeanUtils.copyProperties(po,vo1);
                        return vo1;
                    })
                    .collect(Collectors.toList());
            vo.setStoreVOList(storeVos);
        }
        //a. vo就是空对象 查不到商家 b vo不空但是店铺空 c 都不空
        return vo;
    }
}
